﻿// -----------------------------------------------------------------------
// <copyright company="Christoph van der Fecht - VDsoft">
// Copyright (C) Christoph van der Fecht - VDsoft - All Rights Reserved
// Unauthorized copying of this file, via any medium is strictly prohibited,
// unless it is communicated and authorized by the copyright owner.
// </copyright>
// -----------------------------------------------------------------------

namespace SeriesManager.ViewModel
{
	using System;
	using System.Collections.Generic;
	using System.Linq;
	using System.Text;
	using System.Threading.Tasks;
	using System.Windows.Forms;
	using GalaSoft.MvvmLight;
	using GalaSoft.MvvmLight.Command;
	using Model;
	using SeriesManager.DataLayer;
using System.Threading;
	using System.Windows;


	/// <summary>
	/// TODO: Update Docu.
	/// </summary>
	public class EpisodeManagerViewModel : ViewModelBase
	{
		/// <summary>
		/// Name of the <see cref="SeasonPath"/> property.
		/// </summary>
		private const string SeasonPathName = "SeasonPath";

		/// <summary>
		/// Name of the <see cref="Series"/> property.
		/// </summary>
		private const string SeriesName = "Series";

		/// <summary>
		/// Name of the <see cref="SelectedSeason"/> property.
		/// </summary>
		private const string SelectedSeasonName = "SelectedSeason";

		/// <summary>
		/// Name of the <see cref="IsProgressbarVisible"/> property.
		/// </summary>
		private const string IsProgressbarVisibleName = "IsProgressbarVisible";

		/// <summary>
		/// Path of the season the edit.
		/// </summary>
		private string seasonPath = string.Empty;

		/// <summary>
		/// The series to edit.
		/// </summary>
		private Series series = null;

		/// <summary>
		/// Currently selected season.
		/// </summary>
		private Season selectedSeason = null;

		/// <summary>
		/// Value indicating whether the progressbar is visible or not.
		/// </summary>
		private Visibility isProgressbarVisible = Visibility.Hidden;

		/// <summary>
		/// Thread to rename all episodes.
		/// </summary>
		private Thread renamingThread = null;

		#region private commands

		/// <summary>
		/// Command to show the search dialog.
		/// </summary>
		private RelayCommand showSearchDialogCommand = null;

		/// <summary>
		/// Command to rename all episodes.
		/// </summary>
		private RelayCommand renameEpisodesCommand = null;

		/// <summary>
		/// Command to browse for the season.
		/// </summary>
		private RelayCommand browseSeasonCommand = null;

		#endregion

		/// <summary>
		/// Initializes a new instance of the <see cref="EpisodeManagerViewModel"/> class.
		/// </summary>
		public EpisodeManagerViewModel()
		{
			if (this.IsInDesignMode)
			{
				this.SeasonPath = @"c:\some\folder\path\with a Series\";

				Series dummySeries = new Series();
				dummySeries.Name = "Green Arrow jgy";

				Season season1 = new Season(dummySeries, 1);

				Episode episode0101 = new Episode()
				{
					Name = "Pilot",
					Number = 1
				};

				Episode episode0102 = new Episode()
				{
					Name = "First strike",
					Number = 2
				};

				season1.AddEpisode(episode0101);
				season1.AddEpisode(episode0102);

				Season season2 = new Season(dummySeries, 2);

				Episode episode0201 = new Episode()
				{
					Name = "It goes on!",
					Number = 1
				};

				Episode episode0202 = new Episode()
				{
					Name = "The new guy.",
					Number = 2
				};

				season2.AddEpisode(episode0201);
				season2.AddEpisode(episode0202);

				dummySeries.AddSeason(season1);
				dummySeries.AddSeason(season2);

				this.Series = dummySeries;
				this.SelectedSeason = season1;
				this.IsProgressbarVisible = Visibility.Hidden;
			}
			else
			{
				MessengerInstance.Register<Series>(this, ViewModelLocator.SeriesDetailsToken, this.ReceiveSeriesDetails);
			}
		}

		/// <summary>
		/// Gets or sets the Path of the season the edit.
		/// </summary>
		public string SeasonPath
		{
			get
			{
				return this.seasonPath;
			}

			set
			{
				if (value == this.seasonPath)
				{
					return;
				}

				this.seasonPath = value;
				this.RaisePropertyChanged(SeasonPathName);
			}
		}

		/// <summary>
		/// Gets or sets the The series to edit.
		/// </summary>
		public Model.Series Series
		{
			get
			{
				return this.series;
			}

			private set
			{
				if (value == this.series)
				{
					return;
				}

				this.series = value;
				this.RaisePropertyChanged(SeriesName);
			}
		}

		/// <summary>
		/// Gets or sets the Currently selected season.
		/// </summary>
		public Season SelectedSeason
		{
			get
			{
				return this.selectedSeason;
			}

			set
			{
				if (value == this.selectedSeason)
				{
					return;
				}

				this.selectedSeason = value;
				this.RaisePropertyChanged(SelectedSeasonName);
			}
		}

		/// <summary>
		/// Gets or set a value indicating whether the progress bar is visible or not.
		/// </summary>
		public Visibility IsProgressbarVisible
		{
			get
			{
				return this.isProgressbarVisible;
			}

			set
			{
				if (value == this.isProgressbarVisible)
				{
					return;
				}

				this.isProgressbarVisible = value;
				this.RaisePropertyChanged(IsProgressbarVisibleName);
			}
		}

		#region public commands

		/// <summary>
		/// Gets the command to search for a series.
		/// </summary>
		public RelayCommand ShowSearchDialogCommand
		{
			get
			{
				if (this.showSearchDialogCommand == null)
				{
					this.showSearchDialogCommand = new RelayCommand(this.ShowSearchDialog);
				}

				return this.showSearchDialogCommand;
			}
		}

		/// <summary>
		/// Gets the command to rename all episodes.
		/// </summary>
		public RelayCommand RenameEpisodesCommand
		{
			get
			{
				if (this.renameEpisodesCommand == null)
				{
					this.renameEpisodesCommand = new RelayCommand(this.RenameEpisodes);
				}

				return this.renameEpisodesCommand;
			}
		}

		/// <summary>
		/// Gets the command to browes for the season.
		/// </summary>
		public RelayCommand BrowseSeasonCommand
		{
			get
			{
				if (this.browseSeasonCommand == null)
				{
					this.browseSeasonCommand = new RelayCommand(this.BrowseSeason);
				}

				return this.browseSeasonCommand;
			}
		}

		#endregion

		/// <summary>
		/// Sets the series to provided one.
		/// </summary>
		/// <param name="toSet">Series to set.</param>
		public void SetSeries(Series toSet)
		{
			if (toSet == null)
			{
				return;
			}

			this.Series = toSet;
		}

		/// <summary>
		/// Shows the dialog to search for a series.
		/// </summary>
		private void ShowSearchDialog()
		{
			SearchSeries dialog = new SearchSeries();
			dialog.ShowDialog();
		}

		/// <summary>
		/// Browses for the folder that contains the season.
		/// </summary>
		private void BrowseSeason()
		{
			System.Windows.Forms.FolderBrowserDialog dialog = new System.Windows.Forms.FolderBrowserDialog();
			dialog.SelectedPath = this.SeasonPath;

			if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
			{
				this.SeasonPath = dialog.SelectedPath;
			}
		}

		/// <summary>
		/// Starts the renaming of all episodes.
		/// </summary>
		private void RenameEpisodes()
		{
			if (string.IsNullOrEmpty(this.SeasonPath))
			{
				string message = "Pleas select the path of the series you want to rename";
				string caption = "Warning";
				System.Windows.Forms.MessageBox.Show(message, caption, MessageBoxButtons.OK, MessageBoxIcon.Warning);
			}

			if (this.renamingThread != null)
			{
				this.renamingThread.Abort();
				this.renamingThread = null;
			}

			this.renamingThread = new Thread(new ThreadStart(this.StartRenaming));
			this.renamingThread.Start();
		}

		/// <summary>
		/// Renames all found series.
		/// </summary>
		private void StartRenaming()
		{
			this.IsProgressbarVisible = Visibility.Visible;
			if (this.Series == null)
			{
				////string message = "No Series is selected. Please search a series.";
				////string caption = "Error";
				////MessageBox.Show(message, caption, MessageBoxButtons.OK, MessageBoxIcon.Error);
				return;
			}

			try
			{
				FileManager.Instance.RenameSeries(this.Series, this.SeasonPath);
			}
			catch (Exception ex)
			{
				////string message = string.Concat("An error occured while renameing the series.", ex.Message);
				////string caption = "Error";
				////MessageBox.Show(message, caption, MessageBoxButtons.OK, MessageBoxIcon.Error);
				this.IsProgressbarVisible = Visibility.Hidden;
				return;
			}

			this.IsProgressbarVisible = Visibility.Hidden;
			this.SeasonPath = string.Empty;
		}

		/// <summary>
		/// Receives all details of a series.
		/// </summary>
		/// <param name="received">Details of the series.</param>
		private void ReceiveSeriesDetails(Model.Series received)
		{
			if (received == null)
			{
				return;
			}

			this.Series = received;
		}
	}
}
